import os
import string
from ruamel import yaml
import autoconf_depends

library_dic = {}
condition = 'buildRequires'
in_if = 0
if_condition = []
if_pop = []


def parse(path):
    commands = to_line(path)
    for line in commands:
        if line.startswith('SUBDIRS'):
            subdirs_command(path, line)
        if line.startswith('if'):
            if_command(line)
        if line.startswith('else if'):
            else_if_command(line)
        if line.startswith('else'):
            else_command(line)
        if line.startswith('endif'):
            endif_command(line)
        correspond_var(line)


def correspond_var(line):
    var_name = line[:first_param(line)]
    if var_name.endswith('LIBS') or var_name.endswith('LDADD') or var_name.endswith('LIBADD'):
        print(line)
        lib = line[line.find('=') + 1:].split()
        print(lib)
        library_dic.setdefault(condition, set()).update(lib)


def first_param(line):
    for index in range(len(line)):
        if not (('A' <= line[index] <= 'Z') or line[index] == '_' or ('a' <= line[index] <= 'z') or (
                '0' <= line[index] <= '9')):
            return index


def if_command(line):
    global in_if, condition
    if_pop.append(True)
    if_condition.append([])
    in_if += 1
    condition += " when " + line[2:].strip()


def else_if_command(line):
    global condition
    if_condition[-1].append(condition[condition.rfind(' when') + 5:])
    condition = condition[:condition.rfind(' when')]
    condition += " when " + line[7:].strip()


def else_command(line):
    global condition
    if_pop[-1] = False
    if_condition[-1].append(condition[condition.rfind(' when') + 5:])
    condition = condition[:condition.rfind(' when')]
    else_condition = if_condition[-1]
    for arg in else_condition:
        condition += ' when not' + arg


def endif_command(line):
    global in_if, condition
    in_if -= 1
    if_condition.pop()
    if if_pop[-1]:
        condition = condition[:condition.rfind(' when')]
    else:
        condition = condition[:condition.find(' when not')]
    if_pop.pop()


def subdirs_command(path, line):
    line = line[line.find('=') + 1:].strip()
    sub_path = [ele for ele in line.split() if len(ele) > 0 and ele != '.']
    for spath in sub_path:
        new_path = path[:path.rfind(os.sep)] + os.sep + spath + os.sep + 'Makefile.am'
        parse(new_path)


def to_line(path):
    commands = []
    a_line = ''
    with open(path, 'r', encoding='utf-8') as makefile_am:
        while True:
            new_line = makefile_am.readline()
            if not new_line:
                if a_line.startswith('include '):
                    commands += to_line(path[:path.rfind(os.sep)] + os.sep + a_line[8:].strip())
                else:
                    commands.append(a_line)
                break
            if '#' in new_line:
                new_line = new_line[:new_line.find('#')]
            if len(new_line) == 0:
                continue
            if new_line[0] in string.whitespace:
                if a_line.endswith('\\'):
                    a_line = a_line[:-1].strip()
                a_line += ' ' + new_line.strip()
            else:
                if a_line.startswith('include '):
                    commands += to_line(path[:path.rfind(os.sep)] + os.sep + a_line[8:].strip())
                else:
                    commands.append(a_line)
                a_line = new_line.strip()
    return commands[1:]


def set_style():
    for key in library_dic:
        library_dic[key] = list(library_dic[key])


def save_auto():
    set_style()
    print(library_dic)
    fn = os.path.join("C:\project\python\cppParser", "autotools.yaml")
    with open(fn, 'w', encoding='utf-8') as file:
        yml = yaml.YAML()
        yml.indent(offset=4)
        yml.dump(library_dic, file)
        # yaml.dump(library_dic, file, Dumper=yaml.RoundTripDumper, default_flow_style=False, allow_unicode=True,
        #           width=10000)

# cyrus-sasl  configure.ac文件错误，移动1134行fi到1119，完成解析

# b = {'ucc'}
# local_path = r'C:\Users\admin\Desktop\dependency-analysis\spec-autoconf'
# for entry in os.listdir(local_path):
#     if entry in b: continue
#     full_path = os.path.join(local_path, entry)
#     if os.path.isdir(full_path):
#         a = autoconf_depends.AutoconfDepends()
#         a.load_configure_ac(os.path.join(full_path, 'configure.ac'))
#         a.run_all()

if __name__ == '__main__':
    ban_dir = {'bug01','bug02','can-util'}
    local_path = r'D:\Iron\Work\spec-test\autotoolTest\swtpm'
    for entry in os.listdir(local_path):
        if entry in ban_dir: continue
        full_path = os.path.join(local_path, entry)
        if os.path.isdir(full_path):
            # print(full_path)
            a = autoconf_depends.AutoconfDepends()
            a.load_configure_ac(os.path.join(full_path, 'configure.ac'))
            # a.save_only_depends(full_path,{},"my.yaml")
            a.run_all()